package core;

import javax.sql.DataSource;
import java.sql.*;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;


/**
 * Class of game DB functions.
 *
 * @author eric, Supakit, Devang, Zoran, Kaven, Gary, Jason, Sara, Ming, Nick
 */
public class GameDB {

    // The GameServer object.
    private GameServer server;
    // DataSource object.
    private DataSource dataSource;
    

    /**
     * Connects to the DB.
     *
     * TODO: is this thread-safe?  What
     * can be done to use threads efficiently
     * in a multi-threaded environment?
     * @throws SQLException
     */
    public GameDB(GameServer gameServer) throws SQLException {
        this.server = gameServer;

        GameServerConfig gameConfigReader = gameServer.getGameConfigReader();

        String connectURI = "jdbc:mysql://" + gameConfigReader.getDBUrl()
                + "/" + gameConfigReader.getDBName() + "?" + "user=" + gameConfigReader.getDBUser()
                + "&password=" + gameConfigReader.getDBPassword();
        

        //
        // Then, we set up the PoolingDataSource.
        // Normally this would be handled auto-magically by
        // an external configuration, but in this example we'll
        // do it manually.
        //

        dataSource = ConnectionPool.setupDataSource(connectURI);
    }

    
    public void resetOnlineStatus() {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `user` SET `online` = 0"
                    + " WHERE `online` != 0");
            ps.executeUpdate();

            ps.close();

            ps = connection.prepareStatement("UPDATE `character` SET `online` = 0"
                    + " WHERE `online` != 0");
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /*man-
    public boolean checkInventorySpace(GameItem item, int char_id) {
        List<GameItem> itemList = new ArrayList<GameItem>();
        itemList.add(item);

        return checkInventorySpace(itemList, char_id);
    }

    public boolean checkInventorySpace(List<GameItem> itemList, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = true;

        int amount = getAvailableSlots(char_id);

        if (!itemList.isEmpty() && itemList.size() > amount) {
            List<Short> stackableItems = new ArrayList<Short>();
            List<Short> uniqueItems = new ArrayList<Short>();

            for (GameItem item : itemList) {
                short item_id = item.getItemID();

                if (item.getType() == Constants.ITEM_TYPE_CONSUMABLE) {
                    if (!stackableItems.contains(item_id)) {
                        stackableItems.add(item_id);
                    }

                    if (!uniqueItems.contains(item_id)) {
                        uniqueItems.add(item_id);
                    }
                } else if (item.getType() == Constants.ITEM_TYPE_ARMOR || item.getType() == Constants.ITEM_TYPE_WEAPON) {
                    uniqueItems.add(item_id);
                }
            }

            int count = 0;

            if (!stackableItems.isEmpty()) {
                try {
                    connection = dataSource.getConnection();

                    String query = "SELECT COUNT(DISTINCT `item_id`) AS count FROM `inventory` WHERE `char_id` = ? AND (";

                    for (short item_id : stackableItems) {
                        query += "`item_id` = " + item_id;

                        if (item_id != stackableItems.get(stackableItems.size() - 1)) {
                            query += " OR ";
                        } else {
                            query += ")";
                        }
                    }

                    ps = connection.prepareStatement(query);
                    ps.setInt(1, char_id);

                    rs = ps.executeQuery();

                    if (rs.next()) {
                        count = rs.getInt("count");
                    }
                } catch (SQLException e) {
                    e.printStackTrace(System.err);
                } finally {
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace(System.err);
                    }

                    try {
                        ps.close();
                    } catch (SQLException e) {
                        e.printStackTrace(System.err);
                    }

                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace(System.err);
                    }
                }
            }

            status = uniqueItems.size() - count <= amount;
        }

        return status;
    }

    public void addToInventory(GameItem item) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            if (item.getID() > 0) {
                ps = connection.prepareStatement("SELECT * FROM `inventory`"
                        + " WHERE `inventory_id` = ? AND `char_id` = ?");
                ps.setInt(1, item.getID());
                ps.setInt(2, item.getCharacterID());

                rs = ps.executeQuery();

                if (rs.next()) {
                    int amount = rs.getShort("amount");

                    ps.close();

                    ps = connection.prepareStatement("UPDATE `inventory` SET"
                            + " `amount` = ? WHERE `inventory_id` = ?");
                    ps.setInt(1, amount + item.getAmount());
                    ps.setInt(2, item.getID());
                } else {
                    ps.close();

                    ps = connection.prepareStatement("INSERT INTO `inventory`"
                            + " (`inventory_id`, `char_id`, `slot_num`,"
                            + " `item_id`, `amount`) VALUES (?, ?, ?, ?, ?)");
                    ps.setInt(1, item.getID());
                    ps.setInt(2, item.getCharacterID());
                    ps.setShort(3, item.getSlotNum());
                    ps.setShort(4, item.getItemID());
                    ps.setShort(5, item.getAmount());
                }

                ps.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public GameItem addToInventory(GameItem item, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory`"
                    + " WHERE `char_id` = ? AND `item_id` = ?");
            ps.setInt(1, char_id);
            ps.setShort(2, item.getItemID());

            rs = ps.executeQuery();

            if (item.getType() == Constants.ITEM_TYPE_CONSUMABLE) {
                if (status = rs.next()) {
                    item.setID(rs.getInt("inventory_id"));
                    item.setSlotNum(rs.getShort("slot_num"));

                    int amount = rs.getShort("amount");

                    ps.close();

                    ps = connection.prepareStatement("UPDATE `inventory`"
                            + " SET `amount` = ? WHERE `inventory_id` = ?");
                    ps.setInt(1, amount + item.getAmount());
                    ps.setInt(2, item.getID());
                    ps.executeUpdate();
                }
            }

            if (!status || item.getType() == Constants.ITEM_TYPE_ARMOR || item.getType() == Constants.ITEM_TYPE_WEAPON) {
                short slot_num = getAvailableInventorySlot(char_id);

                if (slot_num >= 0 && slot_num < Constants.MAX_INVENTORY_SIZE) {
                    rs.close();
                    ps.close();

                    ps = connection.prepareStatement("SELECT * FROM `inventory`"
                            + " WHERE `inventory_id` = ?");
                    ps.setInt(1, item.getID());

                    rs = ps.executeQuery();

                    if (item.getID() > 0 && !rs.next()) {
                        ps.close();

                        ps = connection.prepareStatement("INSERT INTO `inventory`"
                                + " (`inventory_id`, `char_id`, `slot_num`,"
                                + " `item_id`, `amount`) VALUES (?, ?, ?, ?, ?)");
                        ps.setInt(1, item.getID());
                        ps.setInt(2, char_id);
                        ps.setShort(3, slot_num);
                        ps.setShort(4, item.getItemID());
                        ps.setShort(5, item.getAmount());
                        ps.executeUpdate();
                    } else {
                        rs.close();
                        ps.close();

                        ps = connection.prepareStatement("INSERT INTO `inventory`"
                                + " (`char_id`, `slot_num`, `item_id`, `amount`) VALUES(?, ?, ?, ?)",
                                Statement.RETURN_GENERATED_KEYS);
                        ps.setInt(1, char_id);
                        ps.setShort(2, slot_num);
                        ps.setShort(3, item.getItemID());
                        ps.setShort(4, item.getAmount());
                        ps.executeUpdate();

                        rs = ps.getGeneratedKeys();

                        if (rs.next()) {
                            item.setID(rs.getInt(1));
                        }
                    }

                    item.setCharacterID(char_id);
                    item.setSlotNum(slot_num);
                } else {
                    item = null;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return item;
    }

    public short getAvailableInventorySlot(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        short slot = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT DISTINCT `slot_num` FROM `inventory`"
                    + " WHERE `char_id` = ? AND `equipped` = 0 ORDER BY `slot_num`");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            short slot_num = 0;

            while (rs.next() && slot_num < Constants.MAX_INVENTORY_SIZE) {
                if (slot_num == rs.getShort("slot_num")) {
                    slot_num++;
                } else {
                    break;
                }
            }

            if (slot_num < Constants.MAX_INVENTORY_SIZE) {
                slot = slot_num;
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return slot;
    }

    public GameItem removeFromInventory(int inventory_id, int amount, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameItem item = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory` WHERE"
                    + " `inventory_id` = ? AND `char_id` = ?");
            ps.setInt(1, inventory_id);
            ps.setInt(2, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                item = new GameItem(inventory_id);

                item.setCharacterID(rs.getInt("char_id"));
                item.setSlotNum(rs.getShort("slot_num"));
                item.setItemID(rs.getShort("item_id"));
                item.setAmount((short) amount);

                amount = rs.getShort("amount") - amount;

                if (amount < 0) {
                    item.setAmount(rs.getShort("amount"));
                }

                ps.close();

                if (amount > 0) {
                    ps = connection.prepareStatement("UPDATE `inventory`"
                            + " SET `amount` = ? WHERE `inventory_id` = ?");
                    ps.setInt(1, amount);
                    ps.setInt(2, inventory_id);
                } else {
                    ps = connection.prepareStatement("DELETE FROM `inventory`"
                            + " WHERE `inventory_id` = ?");
                    ps.setInt(1, inventory_id);
                }

                ps.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return item;
    }

    public List<GameItem> moveInventory(int inventory_id, short to_slot, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameItem> itemList = new ArrayList<GameItem>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory`"
                    + " WHERE `char_id` = ? AND `slot_num` = ? AND `equipped` = 0");
            ps.setInt(1, char_id);
            ps.setShort(2, to_slot);

            rs = ps.executeQuery();

            if (rs.next()) {
                int to_inventory_id = rs.getInt("inventory_id");

                rs.close();
                ps.close();

                ps = connection.prepareStatement("SELECT * FROM `inventory`"
                        + " WHERE `inventory_id` = ? AND `char_id` = ?");
                ps.setInt(1, inventory_id);
                ps.setInt(2, char_id);

                rs = ps.executeQuery();

                if (rs.next()) {
                    short from_slot = rs.getShort("slot_num");

                    ps.close();

                    ps = connection.prepareStatement("UPDATE `inventory` SET"
                            + " `slot_num` = ? WHERE `inventory_id` = ?");
                    ps.setShort(1, from_slot);
                    ps.setInt(2, to_inventory_id);
                    ps.executeUpdate();

                    GameItem item = new GameItem(to_inventory_id);
                    item.setSlotNum(from_slot);

                    itemList.add(item);
                }
            }

            ps.close();

            ps = connection.prepareStatement("UPDATE `inventory` SET"
                    + " `slot_num` = ? WHERE `inventory_id` = ?");
            ps.setShort(1, to_slot);
            ps.setInt(2, inventory_id);
            ps.executeUpdate();

            GameItem item = new GameItem(inventory_id);
            item.setSlotNum(to_slot);

            itemList.add(item);
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return itemList;
    }*/

    /*man-

    public List<GameCharacter> getParty(int party_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameCharacter> partyList = new ArrayList<GameCharacter>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `party_id` = ?");
            ps.setInt(1, party_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                int leader_id = rs.getInt("leader_id");

                rs.close();
                ps.close();

                ps = connection.prepareStatement("SELECT * FROM `character` WHERE `party_id` = ?");
                ps.setInt(1, party_id);

                rs = ps.executeQuery();

                while (rs.next()) {
                    GameCharacter character = new GameCharacter(rs.getInt("char_id"));

                    character.setName(rs.getString("name"));
                    character.setLevel(rs.getShort("level"));
                    character.setModelID(rs.getShort("model_id"));
                    character.setOnline(rs.getBoolean("online"));

                    if (character.getID() != leader_id) {
                        partyList.add(character);
                    } else {
                        partyList.add(0, character);
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return partyList;
    }

    public List<Integer> getPartyIDList(int party_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<Integer> idList = new ArrayList<Integer>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `party_id` = ?");
            ps.setInt(1, party_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                int leader_id = rs.getInt("leader_id");

                rs.close();
                ps.close();

                ps = connection.prepareStatement("SELECT * FROM `character` WHERE `party_id` = ?");
                ps.setInt(1, party_id);

                rs = ps.executeQuery();

                while (rs.next()) {
                    int member_id = rs.getInt("char_id");

                    if (member_id != leader_id) {
                        idList.add(member_id);
                    } else {
                        idList.add(0, member_id);
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return idList;
    }

    public String getPartyName(int party_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        String name = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `party_id` = ?");
            ps.setInt(1, party_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                name = rs.getString("name");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return name;
    }

    public void setPartyName(int party_id, String name) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `party` SET `name` = ? WHERE `party_id` = ?");
            ps.setString(1, name);
            ps.setInt(2, party_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public int getPartyLeader(int party_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int leader_id = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `party_id` = ?");
            ps.setInt(1, party_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                leader_id = rs.getInt("leader_id");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return leader_id;
    }

    public void setPartyLeader(int party_id, int leader_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `party` SET `leader_id` = ? WHERE `party_id` = ?");
            ps.setInt(1, leader_id);
            ps.setInt(2, party_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public int getPartySize(int party_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int size = 0;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT COUNT(*) AS count FROM `character` WHERE `party_id` = ?");
            ps.setInt(1, party_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                size = rs.getInt("count");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return size;
    }

    public void setPartyID(int party_id, int char_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET"
                    + " `party_id` = ? WHERE `char_id` = ?");
            ps.setInt(1, party_id);
            ps.setInt(2, char_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public int createParty(int char_id, String name) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int party_id = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("INSERT INTO `party` (`leader_id`, `name`) VALUES (?, ?)");
            ps.setInt(1, char_id);
            ps.setString(2, name);
            ps.executeUpdate();

            ps.close();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `leader_id` = ? AND `name` = ?");
            ps.setInt(1, char_id);
            ps.setString(2, name);

            rs = ps.executeQuery();

            if (rs.next()) {
                party_id = rs.getInt("party_id");

                ps.close();

                ps = connection.prepareStatement("UPDATE `character` SET `party_id` = ? WHERE `char_id` = ?");
                ps.setInt(1, party_id);
                ps.setInt(2, char_id);
                ps.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return party_id;
    }

    public boolean checkPartyName(String name) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `party` WHERE `name` = ?");
            ps.setString(1, name);

            rs = ps.executeQuery();

            status = !rs.next();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    public void removeParty(int party_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET `party_id` = 0 WHERE `party_id` = ?");
            ps.setInt(1, party_id);
            ps.executeUpdate();

            ps.close();

            ps = connection.prepareStatement("DELETE FROM `party` WHERE `party_id` = ?");
            ps.setInt(1, party_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }*/

    /*man-

    public List<GameItem> getEquipments(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameItem> equipmentList = new ArrayList<GameItem>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory` i1,"
                    + " `item` i2 WHERE `char_id` = ? AND `equipped` != 0"
                    + " AND i1.item_id = i2.item_id");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameItem item = new GameItem(rs.getInt("inventory_id"));

                item.setCharacterID(rs.getInt("char_id"));
                item.setItemID(rs.getShort("item_id"));
                item.setName(rs.getString("name"));
                item.setType(rs.getShort("type"));
                item.setPriceBuy(rs.getInt("price_buy"));
                item.setPriceSell(rs.getInt("price_sell"));
                item.setAmount(rs.getShort("amount"));

                if (item.getType() == Constants.ITEM_TYPE_ARMOR) {
                    item.setDefense(rs.getShort("defense"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                } else if (item.getType() == Constants.ITEM_TYPE_WEAPON) {
                    item.setAttackMin(rs.getInt("atk_min"));
                    item.setAttackMax(rs.getInt("atk_max"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                }

                item.setEffects(rs.getString("effects"));

                equipmentList.add(item);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return equipmentList;
    }

    public void setEquipmentStatus(int inventory_id, int char_id, short equip_location, boolean status) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `inventory` SET"
                    + " `equipped` = ? WHERE `inventory_id` = ?");
            ps.setBoolean(1, status);
            ps.setInt(2, inventory_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public short removeEquipment(int inventory_id, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        short status = 0;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory`"
                    + " WHERE `char_id` = ? AND `equipped` = 0 ORDER BY `slot_num`");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            short slot_num = 0;

            while (rs.next() && slot_num < Constants.MAX_INVENTORY_SIZE) {
                if (slot_num == rs.getShort("slot_num")) {
                    slot_num++;
                } else {
                    break;
                }
            }

            if (slot_num < Constants.MAX_INVENTORY_SIZE) {
                ps.close();

                ps = connection.prepareStatement("UPDATE `inventory` SET"
                        + " `slot_num` = ? WHERE `inventory_id` = ?");
                ps.setShort(1, slot_num);
                ps.setInt(2, inventory_id);
                ps.executeUpdate();
            } else {
                status = 1;
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    public void removeEquipment(int inventory_id, int char_id, short slot_num) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `inventory` SET"
                    + " `slot_num` = ? WHERE `inventory_id` = ?");
            ps.setShort(1, slot_num);
            ps.setInt(2, inventory_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public List<GameItem> getInventory(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameItem> inventory = new ArrayList<GameItem>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory` i1,"
                    + " `item` i2 WHERE `char_id` = ? AND `equipped` = 0"
                    + " AND i1.item_id = i2.item_id");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameItem item = new GameItem(rs.getInt("inventory_id"));

                item.setCharacterID(rs.getInt("char_id"));
                item.setSlotNum(rs.getShort("slot_num"));
                item.setItemID(rs.getShort("item_id"));
                item.setName(rs.getString("name"));
                item.setType(rs.getShort("type"));
                item.setPriceBuy(rs.getInt("price_buy"));
                item.setPriceSell(rs.getInt("price_sell"));
                item.setAmount(rs.getShort("amount"));

                if (item.getType() == Constants.ITEM_TYPE_ARMOR) {
                    item.setDefense(rs.getShort("defense"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                } else if (item.getType() == Constants.ITEM_TYPE_WEAPON) {
                    item.setAttackMin(rs.getInt("atk_min"));
                    item.setAttackMax(rs.getInt("atk_max"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                }

                item.setEffects(rs.getString("effects"));

                inventory.add(item);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return inventory;
    }

    public GameItem getItemFromInventory(int inventory_id, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameItem item = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `inventory` i1,"
                    + " `item` i2 WHERE `inventory_id` = ? AND `char_id` = ? AND"
                    + " i1.item_id = i2.item_id");
            ps.setInt(1, inventory_id);
            ps.setInt(2, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                item = new GameItem(rs.getInt("inventory_id"));

                item.setCharacterID(rs.getInt("char_id"));
                item.setSlotNum(rs.getShort("slot_num"));
                item.setItemID(rs.getShort("item_id"));
                item.setName(rs.getString("name"));
                item.setType(rs.getShort("type"));
                item.setPriceBuy(rs.getInt("price_buy"));
                item.setPriceSell(rs.getInt("price_sell"));
                item.setAmount(rs.getShort("amount"));

                if (item.getType() == Constants.ITEM_TYPE_ARMOR) {
                    item.setDefense(rs.getShort("defense"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                } else if (item.getType() == Constants.ITEM_TYPE_WEAPON) {
                    item.setAttackMin(rs.getInt("atk_min"));
                    item.setAttackMax(rs.getInt("atk_max"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                }

                item.setEffects(rs.getString("effects"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return item;
    }

    public GameItem getItem(short item_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameItem item = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `item` WHERE `item_id` = ?");
            ps.setShort(1, item_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                item = new GameItem(-1);

                item.setItemID(rs.getShort("item_id"));
                item.setName(rs.getString("name"));
                item.setType(rs.getShort("type"));
                item.setPriceBuy(rs.getInt("price_buy"));
                item.setPriceSell(rs.getInt("price_sell"));

                if (item.getType() == Constants.ITEM_TYPE_ARMOR) {
                    item.setDefense(rs.getShort("defense"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                } else if (item.getType() == Constants.ITEM_TYPE_WEAPON) {
                    item.setAttackMin(rs.getInt("atk_min"));
                    item.setAttackMax(rs.getInt("atk_max"));
                    item.setEquipLocation(rs.getShort("equip_location"));
                    item.setEquipLevel(rs.getShort("equip_level"));
                    item.setView(rs.getShort("view"));
                }

                item.setEffects(rs.getString("effects"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return item;
    }

    public GameItem getItem(short item_id, short amount) {
        GameItem item = getItem(item_id);

        if (item != null) {
            item.setAmount(amount);
        }

        return item;
    }

    public List<GameItem> getItemDropsFromBug(int bug_id, float modifier) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameItem> itemList = new ArrayList<GameItem>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `bug` WHERE `bug_id` = ?");
            ps.setInt(1, bug_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                int max_items = 3;

                for (int i = 1; i <= max_items; i++) {
                    short item_id = rs.getShort("drop" + i + "_id");
                    float drop_rate = rs.getFloat("drop" + i + "_rate") * Constants.ITEM_DROP_RATE;

                    drop_rate = (drop_rate > 1) ? 1 : drop_rate;

                    if (new Random().nextFloat() * modifier < drop_rate) {
                        GameItem item = getItem(item_id);

                        if (item != null) {
                            itemList.add(item);
                        }
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return itemList;
    }

    public int getAvailableSlots(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int amount = 0;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT COUNT(*) AS count FROM `inventory`"
                    + " WHERE `char_id` = ? AND `equipped` = 0");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                amount = Constants.MAX_INVENTORY_SIZE - rs.getInt("count");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return amount;
    }

    public List<GameItem> getRandomItem(int amount, int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameItem> itemList = new ArrayList<GameItem>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `item` ORDER BY rand() LIMIT ?");
            ps.setInt(1, amount);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameItem item = getItem(rs.getShort("item_id"));

                if (item != null) {
                    item = addToInventory(item, char_id);
                    itemList.add(item);

                    if (item == null) {
                        break;
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return itemList;
    }*/

    /*man-

    public String getTopic(String topic_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        String topic = "";

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `topic` WHERE `topic_id` = ?");
            ps.setString(1, topic_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                topic = rs.getString("name");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return topic;
    }

    public List<String> getTopicList(short level) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<String> topicList = new ArrayList<String>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `topic` WHERE `level` <= ?");
            ps.setShort(1, level);

            rs = ps.executeQuery();

            while (rs.next()) {
                topicList.add(rs.getString("topic_id"));
                topicList.add(rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return topicList;
    }*/

    public GameQuestion getQuestion(short question_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameQuestion question = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `questions` q, `topic` t WHERE"
                    + " q.topic = t.topic_id AND `id` = ?");
            ps.setShort(1, question_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                question = new GameQuestion(rs.getShort("id"));

                question.setType(rs.getShort("question_type"));
                question.setText(rs.getString("question"));
                question.setAnswer(rs.getShort("correctanswer"));

                List<String> options = new ArrayList<String>();

                if (question.getType() == 1) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                } else if (question.getType() == 2) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                    options.add(rs.getString("option3"));
                    options.add(rs.getString("option4"));
                }

                question.setOptions(options);
                question.setHint(rs.getString("hint"));
                question.setPoints(rs.getInt("points"));
                question.setTime(rs.getInt("timelimit"));
                question.setTopicID(rs.getString("t.topic_id"));
                question.setTopic(rs.getString("t.name"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return question;
    }

    public GameQuestion getQuestion(String topic_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameQuestion question = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `questions` q, `topic` t WHERE"
                    + " q.topic = t.topic_id AND `is_validated` != 0 AND t.topic_id = ? ORDER BY rand() LIMIT 1");
            ps.setString(1, topic_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                question = new GameQuestion(rs.getShort("id"));

                question.setType(rs.getShort("question_type"));
                question.setText(rs.getString("question"));
                question.setAnswer(rs.getShort("correctanswer"));

                List<String> options = new ArrayList<String>();

                if (question.getType() == 1) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                } else if (question.getType() == 2) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                    options.add(rs.getString("option3"));
                    options.add(rs.getString("option4"));
                }

                question.setOptions(options);
                question.setHint(rs.getString("hint"));
                question.setPoints(rs.getInt("points"));
                question.setTime(rs.getInt("timelimit"));
                question.setTopicID(rs.getString("t.topic_id"));
                question.setTopic(rs.getString("t.name"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return question;
    }

    public GameQuestion getQuestion(String topic_id, List<Short> excludeList) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameQuestion question = null;

        try {
            connection = dataSource.getConnection();

            String query = "SELECT * FROM `questions` q, `topic` t WHERE";

            for (short question_id : excludeList) {
                query += " `id` != " + question_id + " AND";
            }

            query += " q.topic = t.topic_id AND `is_validated` != 0 AND `topic_id` = ? ORDER BY rand() LIMIT 1";

            ps = connection.prepareStatement(query);
            ps.setString(1, topic_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                question = new GameQuestion(rs.getShort("id"));

                question.setType(rs.getShort("question_type"));
                question.setText(rs.getString("question"));
                question.setAnswer(rs.getShort("correctanswer"));

                List<String> options = new ArrayList<String>();

                if (question.getType() == 1) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                } else if (question.getType() == 2) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                    options.add(rs.getString("option3"));
                    options.add(rs.getString("option4"));
                }

                question.setOptions(options);
                question.setHint(rs.getString("hint"));
                question.setPoints(rs.getInt("points"));
                question.setTime(rs.getInt("timelimit"));
                question.setTopicID(rs.getString("t.topic_id"));
                question.setTopic(rs.getString("t.name"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return question;
    }

    public int validateUser(String username, String password) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int user_id = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `user` WHERE"
                    + " `username` = ? AND `password` = MD5(?)");
            ps.setString(1, username);
            ps.setString(2, password);

            rs = ps.executeQuery();

            if (rs.next()) {
                user_id = rs.getInt("user_id");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return user_id;
    }
    
    public void getUser(int user_id, GameUser user) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `user` WHERE `user_id` = ?");
            ps.setInt(1, user_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                user.setID(rs.getInt("user_id"));
                user.setUsername(rs.getString("username"));
                user.setStudentID(rs.getInt("student_id"));
                user.setFirstName(rs.getString("first_name"));
                user.setLastName(rs.getString("last_name"));
                user.setGender(rs.getShort("gender"));
                user.setEmail(rs.getString("email"));
                user.setLevel(rs.getShort("level"));
                user.setOnline(rs.getBoolean("online"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /*man-
    public GameBug getBug(int bug_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameBug bug = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `bug` WHERE `bug_id` = ?");
            ps.setInt(1, bug_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                bug = new GameBug(-1);

                bug.setBugID(rs.getInt("bug_id"));
                bug.setName(rs.getString("name"));
                bug.setModelID(rs.getShort("model_id"));
                bug.setTopicID(rs.getString("topic_id"));
                bug.setLevel(rs.getShort("level"));
                bug.setBaseHealth(rs.getInt("health"));
                bug.setBaseAttackPower(rs.getInt("atk_min"), rs.getInt("atk_max"));
                bug.setBaseAttackDelay(rs.getFloat("atk_delay"));
                bug.setBaseAttackRange(rs.getFloat("atk_range"));
                bug.setBaseDefense(rs.getShort("defense"));
                bug.setBaseMoveSpeed(rs.getFloat("move_speed"));
                bug.setBaseScale(rs.getFloat("scale"));
                bug.setMode(rs.getBoolean("mode"));
                bug.setBoss(rs.getShort("boss"));
                bug.setExperience(rs.getInt("experience"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return bug;
    }

    public int getBugExperience(int level) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int experience = 0;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `bug` WHERE `level` = ? AND `boss` = 0");
            ps.setInt(1, level);

            rs = ps.executeQuery();

            if (rs.next()) {
                experience = rs.getInt("experience");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return experience;
    }*/


    
    public GameCharacter getCharacterBySlot(int user_id, int char_num) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameCharacter character = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `user_id` = ? AND `char_num` = ?");
            ps.setInt(1, user_id);
            ps.setInt(2, char_num);

            rs = ps.executeQuery();

            if (rs.next()) {
                character = new GameCharacter(rs.getInt("char_id"));

                character.setUserID(rs.getInt("user_id"));
                character.setName(rs.getString("name"));
                character.setClassID(rs.getShort("class_id"));
                character.setModelID(rs.getShort("model_id"));
                character.setLevel(rs.getShort("level"));
                character.setExperience(rs.getInt("experience"));
                character.setMoney(rs.getInt("money"));

                int atk_power = Math.round(character.getLevel() * 0.75f);

                character.setBaseAttackPower(atk_power, atk_power);
                character.setBaseDefense((short) Math.round(character.getLevel() * 0.45f));
                character.setBaseHealth(100 + (character.getLevel() - 1) * 5 + (int) Math.pow(character.getLevel() / 5, 2));

                character.setPartyID(rs.getInt("party_id"));
                /*
                for (GameItem item : getEquipments(character.getID())) {
                    character.setEquipment(item);
                    GameItemEffectTable.applyEffects(1, item, character);
                }*/

                float health_diff = rs.getFloat("health") / rs.getFloat("max_health");

                if (health_diff > 0) {
                    character.setHealth(Math.round(character.getHealthMax() * health_diff));
                } else {
                    character.setHealth(Math.round(character.getHealthMax() * 0.25f));
                }

                character.setSaveMapID(rs.getString("last_save_map"));
                character.setSaveX(rs.getFloat("last_save_x"));
                character.setSaveY(rs.getFloat("last_save_y"));
                character.setSaveZ(rs.getFloat("last_save_z"));
                character.setMapID(rs.getString("last_map"));
                character.setX(rs.getFloat("last_x"));
                character.setY(rs.getFloat("last_y"));
                character.setZ(rs.getFloat("last_z"));

                setCharacterOnline(character.getID(), 1);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return character;
    }

    public GameCharacter getCharacter(String charName) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameCharacter character = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE `name` = ?");
            ps.setString(1, charName);

            rs = ps.executeQuery();

            if (rs.next()) {
                character = new GameCharacter(rs.getInt("char_id"));

                character.setUserID(rs.getInt("user_id"));
                character.setName(rs.getString("name"));
                character.setClassID(rs.getShort("class_id"));
                character.setModelID(rs.getShort("model_id"));
                character.setLevel(rs.getShort("level"));
                character.setExperience(rs.getInt("experience"));
                character.setMoney(rs.getInt("money"));
                character.setHealth(rs.getInt("health"), rs.getInt("max_health"));
                character.setPartyID(rs.getInt("party_id"));

                /*
                for (GameItem item : getEquipments(character.getID())) {
                    character.setEquipment(item);
                }*/

                character.setSaveMapID(rs.getString("last_save_map"));
                character.setSaveX(rs.getFloat("last_save_x"));
                character.setSaveY(rs.getFloat("last_save_y"));
                character.setSaveZ(rs.getFloat("last_save_z"));
                character.setMapID(rs.getString("last_map"));
                character.setX(rs.getFloat("last_x"));
                character.setY(rs.getFloat("last_y"));
                character.setZ(rs.getFloat("last_z"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return character;
    }

    public int getCharacterID(String name) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        int char_id = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `name` = ?");
            ps.setString(1, name);

            rs = ps.executeQuery();

            if (rs.next()) {
                char_id = rs.getInt("char_id");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return char_id;
    }

    /**
     * Registered a user
     * @param name username
     * @param password password
     * @return new User object, or null if name/pass is invalid.
     */
    /*man-
    public GameUser createUser(String username, String password, int student_id,
            String first_name, String last_name, short gender, String email, String last_ip) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        GameUser user = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("INSERT INTO `user` (`username`, `password`,"
                    + " `student_id`, `first_name`, `last_name`, `gender`, `email`, `last_ip`)"
                    + " VALUES (?, MD5(?), ?, ?, ?, ?, ?, ?)");
            ps.setString(1, username);
            ps.setString(2, password);
            ps.setInt(3, student_id);
            ps.setString(4, first_name);
            ps.setString(5, last_name);
            ps.setShort(6, gender);
            ps.setString(7, email);
            ps.setString(8, last_ip);
            ps.executeUpdate();

            ps.close();

            ps = connection.prepareStatement("SELECT * FROM `user` WHERE"
                    + " `username` = ?");
            ps.setString(1, username);

            rs = ps.executeQuery();

            if (rs.next()) {
                user = new GameUser(rs.getInt("user_id"));

                user.setUsername(username);
                user.setStudentID(student_id);
                user.setFirstName(first_name);
                user.setLastName(last_name);
                user.setGender(gender);
                user.setEmail(email);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return user;
    }

    public boolean checkUsername(String username) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            // Check if user with given username already exists
            ps = connection.prepareStatement("SELECT * FROM `user` WHERE"
                    + " `username` = ?");
            ps.setString(1, username);

            rs = ps.executeQuery();

            status = !rs.next();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    public boolean checkCharacterName(String name) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `name` = ?");
            ps.setString(1, name);

            rs = ps.executeQuery();

            status = !rs.next();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    public String getCharacterName(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        String name = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `char_id` = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                name = rs.getString("name");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return name;
    }

    public boolean createCharacter(int user_id, int char_num, String name, short model_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character`"
                    + " WHERE `user_id` = ? AND `char_num` = ?");
            ps.setInt(1, user_id);
            ps.setInt(2, char_num);

            rs = ps.executeQuery();

            if (!rs.next()) {
                ps.close();

                ps = connection.prepareStatement("INSERT INTO `character`"
                        + " (`user_id`, `name`, `model_id`) VALUES (?, ?, ?)");
                ps.setInt(1, user_id);
                ps.setString(2, name);
                ps.setShort(3, model_id);
                ps.executeUpdate();

                status = true;
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    public void removeCharacter(int char_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("DELETE FROM `character` WHERE"
                    + " `char_id` = ?");
            ps.setInt(1, char_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public void setLastPosition(int char_id, float[] position) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET `last_x` = ?,"
                    + " `last_y` = ?, `last_z` = ? WHERE `char_id` = ?");
            ps.setFloat(1, position[0]);
            ps.setFloat(2, position[1]);
            ps.setFloat(3, position[2]);
            ps.setInt(4, char_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public String getHotkeys(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        String hotkeysList = "";

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `hotkey` WHERE"
                    + " `char_id` = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                hotkeysList += rs.getShort("slot_num");
                hotkeysList += ",";
                hotkeysList += rs.getShort("type");
                hotkeysList += ":";
                hotkeysList += rs.getShort("item_id");
                hotkeysList += ";";
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return hotkeysList;
    }

    public void addHotkey(int char_id, short slot_num, short type, short item_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `hotkey` WHERE"
                    + " `char_id` = ? AND `slot_num` = ?");
            ps.setInt(1, char_id);
            ps.setShort(2, slot_num);

            rs = ps.executeQuery();

            if (!rs.next()) {
                ps.close();

                ps = connection.prepareStatement("INSERT INTO `hotkey` (`char_id`,"
                        + " `slot_num`, `type`, `item_id`) VALUES (?, ?, ?, ?)");
                ps.setInt(1, char_id);
                ps.setShort(2, slot_num);
                ps.setShort(3, type);
                ps.setShort(4, item_id);
            } else {
                ps.close();

                ps = connection.prepareStatement("UPDATE `hotkey` SET `type` = ?,"
                        + " `item_id` = ? WHERE `char_id` = ? AND `slot_num` = ?");
                ps.setShort(1, type);
                ps.setShort(2, item_id);
                ps.setInt(3, char_id);
                ps.setShort(4, slot_num);
            }

            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public void removeHotkey(int char_id, short slot_num) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("DELETE FROM `hotkey` WHERE"
                    + " `char_id` = ? AND `slot_num` = ?");
            ps.setInt(1, char_id);
            ps.setShort(2, slot_num);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public void moveHotkey(int char_id, short from_slot, short to_slot) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("DELETE FROM `hotkey` WHERE"
                    + " `char_id` = ? AND `slot_num` = ?");
            ps.setInt(1, char_id);
            ps.setShort(2, to_slot);
            ps.executeUpdate();

            ps.close();

            ps = connection.prepareStatement("UPDATE `hotkey` SET `slot_num` = ?"
                    + " WHERE `char_id` = ? AND `slot_num` = ?");
            ps.setShort(1, to_slot);
            ps.setInt(2, char_id);
            ps.setShort(3, from_slot);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }*/


    /**
     * setLastLoginTime
     * @param user_id
     */
    public void setLastLoginTime(int user_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `user` SET `last_login` = ?"
                    + " WHERE `user_id` = ?");
            ps.setTimestamp(1, new Timestamp(new Date().getTime()));
            ps.setInt(2, user_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /**
     * setLastLogoutTime
     * @param user_id
     */
    public void setLastLogoutTime(int user_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `user` SET `last_logout` = ?"
                    + " WHERE `user_id` = ?");
            ps.setTimestamp(1, new Timestamp(new Date().getTime()));
            ps.setInt(2, user_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    public void setLastLoginIP(String address, int user_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `user` SET `last_ip` = ? WHERE"
                    + " `user_id` = ?");
            ps.setString(1, address);
            ps.setInt(2, user_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /**
     * getLastMapID
     * @param char_id
     * @return map_id
     */
    /*man-
    public String getLastMapID(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        String map_id = "1";

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `char_id` = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                map_id = rs.getString("last_map");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return map_id;
    }

    /**
     * setLastMapID
     * @param char_id
     * @param map_id
     * @return true if sceneId updated correctly, or false if not.
     */
    /*
    public void setLastMapID(int char_id, String map_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET `last_map` = ?"
                    + " WHERE `char_id` = ?");
            ps.setString(1, map_id);
            ps.setInt(2, char_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }*/

    public void setUserOnline(int user_id, int status) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `user` SET `online` = ? WHERE"
                    + " `user_id` = ?");
            ps.setInt(1, status);
            ps.setInt(2, user_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    
    public void setCharacterOnline(int char_id, int status) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET `online` = ?"
                    + " WHERE `char_id` = ?");
            ps.setInt(1, status);
            ps.setInt(2, char_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /**
     * Get list of usernames of users present in given scene.
     *
     * @param map_id id of the scene in which user is
     */
    /*
    public List<Integer> getUsersFromMap(String map_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<Integer> userList = new ArrayList<Integer>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE"
                    + " `online` != 0 AND `last_map` = ?");
            ps.setString(1, map_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                userList.add(rs.getInt("char_id"));
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return userList;
    }

    /**
     * Get list of user's buddies.
     * Since that list is stored in the DB as a String, that is what is returned
     * as a result.
     */
    
    public List<GameCharacter> getBuddyList(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameCharacter> buddyList = new ArrayList<GameCharacter>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `buddy` b,"
                    + " `character` c WHERE b.buddy_id = c.char_id AND b.char_id = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameCharacter character = new GameCharacter(rs.getInt("buddy_id"));
                character.setUserID(rs.getInt("user_id"));
                character.setName(rs.getString("name"));
                character.setOnline(rs.getBoolean("online"));
                buddyList.add(character);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return buddyList;
    }
/*
    public List<GameCharacter> getBuddyOnlineList(int char_id, boolean status) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameCharacter> buddyList = new ArrayList<GameCharacter>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `buddy` b,"
                    + " `character` c WHERE b.buddy_id = c.char_id AND b.char_id = ? AND online = ?");
            ps.setInt(1, char_id);
            ps.setBoolean(2, status);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameCharacter character = new GameCharacter(rs.getInt("buddy_id"));
                character.setUserID(rs.getInt("user_id"));
                character.setName(rs.getString("name"));
                character.setOnline(rs.getBoolean("online"));

                buddyList.add(character);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return buddyList;
    }
*/
    /**
     * Add a new buddy's username to the list of user's buddies.
     *
     * @param buddy_id  username of the new buddy
     * @param char_id  user_id of the one whose buddy-list will be expanded
     */
    public boolean addBuddy(int char_id, int buddy_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `buddy` WHERE"
                    + " `char_id` = ? AND `buddy_id` = ?");
            ps.setInt(1, char_id);
            ps.setInt(2, buddy_id);

            rs = ps.executeQuery();

            if (!rs.next()) {
                ps.close();

                ps = connection.prepareStatement("INSERT INTO `buddy` (`char_id`,"
                        + " `buddy_id`) VALUES(?, ?)");
                ps.setInt(1, char_id);
                ps.setInt(2, buddy_id);
                ps.executeUpdate();

                ps.close();

                ps = connection.prepareStatement("INSERT INTO `buddy` (`char_id`,"
                        + " `buddy_id`) VALUES(?, ?)");
                ps.setInt(1, buddy_id);
                ps.setInt(2, char_id);
                ps.executeUpdate();

                status = true;
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }

    /**
     * Remove a buddy's username from the list of user's buddies.
     *
     * @param name  username of the buddy to be removed
     * @param userId  user_id of the one whose buddy-list will be shortened
     *
     */
    public boolean removeBuddy(int char_id, int buddy_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `buddy` WHERE `char_id` = ? AND `buddy_id` = ?");
            ps.setInt(1, char_id);
            ps.setInt(2, buddy_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                ps.close();

                ps = connection.prepareStatement("DELETE FROM `buddy` WHERE"
                        + " (`char_id` = ? AND `buddy_id` = ?) OR"
                        + " (`char_id` = ? AND `buddy_id` = ?)");
                ps.setInt(1, char_id);
                ps.setInt(2, buddy_id);
                ps.setInt(3, buddy_id);
                ps.setInt(4, char_id);
                ps.executeUpdate();

                status = true;
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }


    public List<GameQuestion> getQuestionLog(int char_id, int amount) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        List<GameQuestion> questionList = new ArrayList<GameQuestion>();

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `question_log` q1, `questions` q2, `topic` t"
                    + " WHERE q1.question_id = q2.id AND q2.topic = t.topic_id AND `char_id` = ? ORDER BY `time` DESC");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            while (rs.next()) {
                GameQuestion question = new GameQuestion(rs.getShort("question_id"));

                question.setType(rs.getShort("question_type"));
                question.setText(rs.getString("question"));
                question.setAnswer(rs.getShort("correctanswer"));

                List<String> options = new ArrayList<String>();

                if (question.getType() == 1) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                } else if (question.getType() == 2) {
                    options.add(rs.getString("option1"));
                    options.add(rs.getString("option2"));
                    options.add(rs.getString("option3"));
                    options.add(rs.getString("option4"));
                }

                question.setOptions(options);
                question.setHint(rs.getString("hint"));
                question.setTime(rs.getInt("timelimit"));
                question.setTopicID(rs.getString("t.topic_id"));
                question.setTopic(rs.getString("t.name"));

                question.setChoice(rs.getShort("q1.option"));
                question.setStatus(rs.getBoolean("q1.status"));
                question.setLogTime(new SimpleDateFormat("MM-dd-yyyy HH:mm:ss").format(rs.getTimestamp("q1.time")));

                questionList.add(question);

                if (questionList.size() == amount) {
                    break;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return questionList;
    }
/*
    public short[] getQuestionRatio(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        short[] ratio = new short[2];

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT COUNT(*) as count FROM `question_log`"
                    + " WHERE `char_id` = ? AND `status` = 1");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                ratio[0] = rs.getShort("count");
            }

            rs.close();
            ps.close();

            ps = connection.prepareStatement("SELECT COUNT(*) as count FROM `question_log`"
                    + " WHERE `char_id` = ? AND `status` = 0");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                ratio[1] = rs.getShort("count");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return ratio;
    }

    public boolean createQuestionComment(int user_id, int char_id, int question_id, String subject, String message, short rating) {
        PreparedStatement ps = null;
        Connection connection = null;

        boolean status = false;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("INSERT INTO `comment_log`"
                    + " (`user_id`, `char_id`, `question_id`, `subject`, `message`, `rating`)"
                    + " VALUES (?, ?, ?, ?, ?, ?)");
            ps.setInt(1, user_id);
            ps.setInt(2, char_id);
            ps.setInt(3, question_id);
            ps.setString(4, subject);
            ps.setString(5, message);
            ps.setShort(6, rating);
            ps.executeUpdate();

            status = true;
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return status;
    }*/

    public void createQuestionLog(int user_id, int char_id, int question_id, short option, boolean status) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("INSERT INTO `question_log`"
                    + " (`user_id`, `char_id`, `question_id`, `option`, `status`)"
                    + " VALUES (?, ?, ?, ?, ?)");
            ps.setInt(1, user_id);
            ps.setInt(2, char_id);
            ps.setInt(3, question_id);
            ps.setShort(4, option);
            ps.setBoolean(5, status);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /*man-

    public int createBoardGame(short type, String participants) {
        PreparedStatement ps = null;
        ResultSet rs = null;
        Connection connection = null;

        int board_id = -1;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("INSERT INTO `board_game`"
                    + " (`type`, `participants`) VALUES (?, ?)",
                    Statement.RETURN_GENERATED_KEYS);
            ps.setShort(1, type);
            ps.setString(2, participants);
            ps.executeUpdate();

            rs = ps.getGeneratedKeys();

            if (rs.next()) {
                board_id = rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return board_id;
    }*/

    public void setBoardGameWinner(int board_id, int user_id, int char_id) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `board_game` SET"
                    + "`end_time` = ?, `winner` = ? WHERE `board_id` = ?");
            ps.setTimestamp(1, new Timestamp(new Date().getTime()));

            if (user_id != 0 && char_id != 0) {
                ps.setString(2, user_id + ":" + char_id);
            } else {
                ps.setString(2, "-");
            }

            ps.setInt(3, board_id);
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    /**
     * setPostQuizStatistics
     * @param quiz_id Id of a quiz that was played.
     * @param username Username of a player who won the quiz.
     * @param duration Duration of the quiz, in seconds.
     * @return True if update was successful, false otherwise
     */
    /*
    public boolean setPostQuizStatistics(int quiz_id, String username) {
        PreparedStatement ps = null;
        Connection connection = null;
        ResultSet rs = null;

        Timestamp quizStartTime = null;
        Timestamp quizEndTime = new Timestamp((new java.util.Date()).getTime());
        int durationTimeSeconds = 0;

        // Read the "scheduled time" of the quiz
        try {
            connection = dataSource.getConnection();

            // Set login time for the user
            ps = connection.prepareStatement("SELECT `scheduled_time` FROM"
                    + " `quiz_statistics` WHERE `quiz_id` = ?");
            ps.setInt(1, quiz_id);
            rs = ps.executeQuery();

            if (rs.next()) {
                quizStartTime = rs.getTimestamp("scheduled_time");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        // Calculate duration time of the quiz
        durationTimeSeconds = (int) (quizEndTime.getTime() - quizStartTime.getTime()) / 1000;

        boolean flag = false;

        // Log in quiz statistics
        try {
            connection = dataSource.getConnection();

            // Set login time for the user
            ps = connection.prepareStatement("UPDATE `quiz_statistics` SET"
                    + " `quiz_duration_time` = ?, `winners_username` = ? WHERE `quiz_id` = ?");
            ps.setInt(1, durationTimeSeconds);
            ps.setString(2, username);
            ps.setInt(3, quiz_id);
            ps.executeUpdate();

            flag = true;
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return flag;
    }

    /**
     * setQuizMovementsLogEntry
     * @param quiz_id Id of a quiz played.
     * @param movement_id Id of a move player made.
     * @param username User's username.
     * @return true if all OK, false otherwise
     */
    /*
    public boolean setQuizMovementsLogEntry(int quiz_id, String movement_id, String username) {
        PreparedStatement ps = null;
        Connection connection = null;

        boolean flag = false;

        try {
            connection = dataSource.getConnection();

            // Set login time for the user
            ps = connection.prepareStatement("INSERT INTO `quiz_movements_log`"
                    + " (`quiz_id`, `movement_id`, `username`) VALUES (?, ?, ?)");
            ps.setInt(1, quiz_id);
            ps.setString(2, movement_id);
            ps.setString(3, username);
            ps.executeUpdate();

            flag = true;
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return flag;
    }*/

    /**
     * checkShutdownFlag
     * @return 0 - no flag set, 1 - emergency shutdown, 2 - maintenance shutdown
     */
    /*man-
    public int checkShutdownFlag() {
        PreparedStatement ps = null;
        Connection connection = null;
        ResultSet rs = null;

        String emergencyShutdownSet = "";
        String maintenanceShutdownSet = "";

        int flag = 0;

        try {
            connection = dataSource.getConnection();

            // Read the setting of the emergency shutdown flag
            ps = connection.prepareStatement("SELECT * FROM `game_server` WHERE"
                    + " `variable` = 'emergency_shutdown'");
            rs = ps.executeQuery();

            if (rs.next()) {
                emergencyShutdownSet = rs.getString("value");
                if (emergencyShutdownSet.equalsIgnoreCase("yes")) {
                    flag = 1;
                } else {
                    rs.close();
                    ps.close();

                    // Read the setting of the maintenance shutdown flag
                    ps = connection.prepareStatement("SELECT * FROM `game_server`"
                            + " WHERE `variable` = 'maintenance_shutdown'");
                    rs = ps.executeQuery();

                    if (rs.next()) {
                        maintenanceShutdownSet = rs.getString("value");
                        if (maintenanceShutdownSet.equalsIgnoreCase("yes")) {
                            flag = 2;
                        }
                    }
                }
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return flag;
    }

    /**
     * returnShutdownTime
     * @return Time, as Unix time, when Game Server is to shutdown
     */
    /*
    public long returnShutdownTime(String shutdownType) {
        PreparedStatement ps = null;
        Connection connection = null;
        ResultSet rs = null;

        long shutdownTime = 0;

        try {
            connection = dataSource.getConnection();

            // Read the setting of the emergency shutdown flag
            ps = connection.prepareStatement("SELECT * FROM `game_server` WHERE `variable` = ?");
            ps.setString(1, shutdownType);
            rs = ps.executeQuery();

            if (rs.next()) {
                shutdownTime = rs.getLong("time_stamp");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return shutdownTime;
    }

    /**
     * setShutdownFlag
     * @return True, if flag set successfully, False otherwise
     */
    /*
    public boolean setShutdownFlag(String shutdownFlag, String shutdownValue, long shutdownTimestamp) {
        PreparedStatement ps = null;
        Connection connection = null;

        boolean flag = false;

        try {
            connection = dataSource.getConnection();

            // Read the setting of the emergency shutdown flag
            ps = connection.prepareStatement("UPDATE `game_server` SET `value` = ?,"
                    + " `time_stamp` = ? WHERE `variable` = ?");
            ps.setString(1, shutdownValue);
            ps.setLong(2, shutdownTimestamp);
            ps.setString(3, shutdownFlag);

            flag = true;
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return flag;
    }*/

    /*man-
    public float[] getLastPosition(int char_id) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        float[] position = new float[3];

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE `char_id` = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                position[0] = rs.getFloat("last_x");
                position[1] = rs.getFloat("last_y");
                position[2] = rs.getFloat("last_z");
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }

        return position;
    }*/

    /*man-
    public void setExperience(int char_id, int amount) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `character` WHERE `char_id` = ?");
            ps.setInt(1, char_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                amount += rs.getInt("experience");

                ps.close();

                ps = connection.prepareStatement("UPDATE `character` SET `experience` = ? WHERE `char_id` = ?");
                ps.setInt(1, amount);
                ps.setInt(2, char_id);
                ps.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }*/

    
    public void setPlayTime(int user_id, int amount) {
        ResultSet rs = null;
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("SELECT * FROM `user` WHERE `user_id` = ?");
            ps.setInt(1, user_id);

            rs = ps.executeQuery();

            if (rs.next()) {
                int play_time = rs.getInt("play_time");

                ps.close();

                ps = connection.prepareStatement("UPDATE `user` SET `play_time` = ?"
                        + " WHERE `user_id` = ?");
                ps.setInt(1, play_time + amount);
                ps.setInt(2, user_id);
                ps.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }

    
    public void saveGameUser(GameCharacter character) {
        PreparedStatement ps = null;
        Connection connection = null;

        try {
            connection = dataSource.getConnection();

            ps = connection.prepareStatement("UPDATE `character` SET `model_id` = ?,"
                    + " `level` = ?, `experience` = ?, `money` = ?, `max_health` = ?,"
                    + " `health` = ?, `last_map` = ?, `last_x` = ?, `last_y` = ?,"
                    + " `last_z` = ? WHERE `char_id` = ?");
            ps.setShort(1, character.getModelID());
            ps.setShort(2, character.getLevel());
            ps.setInt(3, character.getExperience());
            ps.setInt(4, character.getMoney());
            ps.setInt(5, character.getHealthMax());
            ps.setInt(6, character.getHealth());
            ps.setString(7, character.getMapID());
            ps.setFloat(8, character.getX());
            ps.setFloat(9, character.getY());
            ps.setFloat(10, character.getZ());
            ps.setInt(11, character.getID());
            ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace(System.err);
        } finally {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }

            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace(System.err);
            }
        }
    }
}

